Skip to content

convert c++ exceptions to r errors in module .External entry points - #1496

Open
kevinushey wants to merge 1 commit into
masterfrom
bugfix/module-uncaught-exceptions
Open

convert c++ exceptions to r errors in module .External entry points#1496
kevinushey wants to merge 1 commit into
masterfrom
bugfix/module-uncaught-exceptions

Conversation

@kevinushey

Copy link
Copy Markdown
Contributor

Fixes #1495.

CppMethod__invoke, CppMethod__invoke_void, CppMethod__invoke_notvoid, and class__newInstance in src/module.cpp are .External entry points that can throw C++ exceptions -- most notably CHECK_DUMMY_OBJ's Rcpp::not_initialized, the designed error for using a module object created via the dummy-object path (new(Class) with no arguments, for a class without a default constructor). With no BEGIN_RCPP/END_RCPP in these functions, the exception escapes into R's C evaluator uncaught and std::terminate() aborts the whole R session, instead of raising the intended R error. See #1495 for details.

Changes:

  • src/module.cpp: wrap the four entry points in BEGIN_RCPP/END_RCPP, so exceptions are converted to R errors as elsewhere in Rcpp. On the not_initialized path this also unwinds the local XPtr objects properly before the R error is raised.
  • inst/tinytest/test_module.R: regression test -- calling a method on an uninitialized ModuleRandomizer must raise the "C++ object not initialized" R error. Without the fix this test aborts the tinytest process.

One pre-existing quirk surfaced while testing (left unchanged, noting it here): when a dummy object is garbage collected, the reference class finalizer calls class_<T>::run_finalizer(), whose XP(object) rejects the dummy pointer (an environment), printing Error: Expecting an external pointer: [type=environment]. at shutdown. That happens on current master for any dummy object whose finalizer runs and is independent of this change; it could be addressed separately by having run_finalizer() (or CppObject__finalize) skip the dummy instance.

Verification:

Checklist

  • Code compiles correctly
  • R CMD check still passes all tests (checked locally with RunAllRcppTests=yes on R 4.6.1; --no-manual --no-vignettes, so the only flagged items were the two vignette-packaging warnings from the local --no-build-vignettes build)
  • Preferably, new tests were added which fail without the change (without the fix, the new test terminates the test process)
  • Document the changes by file in ChangeLog

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

calling a method on an uninitialized module object aborts the R session

1 participant